package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.teenpatti.base.enums.ErrorCodeEnum;
import com.jule.teenpatti.game.dao.bean.CommonConfigModel;
import com.jule.teenpatti.game.gameUtil.GameLogic;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.PlayTypeEnum;
import com.jule.teenpatti.game.model.eenum.PlayerStateEnum;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_ApplySideShowAck_50007;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.play.TableUtil;
import com.jule.teenpatti.game.service.TableService;
import com.jule.teenpatti.game.vavle.notice.NoticeBroadcastMessages;
import io.netty.buffer.ByteBuf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Deprecated
public class JoloGame_ApplySideShowReq_50007 extends ClientReq {
    private final static Logger logger = LoggerFactory.getLogger(JoloGame_ApplySideShowReq_50007.class);

    public JoloGame_ApplySideShowReq_50007(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_ApplySideShowReq req;

    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_ApplySideShowReq.parseFrom(blob);
        this.setTable(TableService.getInstance().getTable(header.gameId+"",req.getRoomId(), req.getTableId()));
    }

    @Override
    public void processImpl() throws Exception {
        long time = System.currentTimeMillis();
        logger.debug("收到消息-> " + functionId + ", reqNum-> " + header.reqNum + ", req->" + req.toString());
        String userId = req.getUserId();
        String roomId = req.getRoomId();
        String tableId = req.getTableId();
        String gameOrderId = req.getGameOrderId();
        String targetUserId = req.getTargetUserId();

        JoloGame.JoloGame_ApplySideShowAck.Builder ack = JoloGame.JoloGame_ApplySideShowAck.newBuilder();

        double betScore = 0;
        //获得桌子信息和玩家信息
        AbstractTable table = getTable();
        try{
            ack.setUserId(userId);
            ack.setRoomId(roomId);
            ack.setTableId(tableId);
            ack.setGameOrderId(gameOrderId);
            ack.setTargetUserId(targetUserId);
            ack.setBetScore(betScore);
            ack.setCurrPlayScore(0);
            //获得玩家信息
            PlayerInfo player = table.getPlayer(userId);

            //获得被比牌用户信息
            PlayerInfo targetPlayer = table.getPlayer(targetUserId);
            if(null == player || null == targetPlayer){
                ack.setResult(-1); //玩家信息不存在
                logger.error("找不到玩家信息。playerIsNull->"+ (null == player) +", targetPlayerIsNull->"+(null == targetPlayer));
                ack.setResultMsg(ErrorCodeEnum.GAME_50050_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                return;
            }

            //如果gameOrderId不一致，那么返回错误
            if(!gameOrderId.equals(table.getCurrGameOrderId())){
                ack.setResult(-1);
                logger.error("GameOrderId不一致, req gameOrderId->"+gameOrderId+", currGameOrderId->"+table.getCurrGameOrderId());
                ack.setResultMsg(ErrorCodeEnum.GAME_50013_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                return;
            }

            if(player.getSeatNum() <= 0){
                logger.warn("player have no seat,can't exec. playerId->"+userId);
                ack.setResult(-1).setResultMsg(ErrorCodeEnum.GAME_50050_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                return;
            }

            if(player.getState().getValue() != PlayerStateEnum.beting.getValue()){
                logger.warn("player state invalid,can't exec. playerId->"+userId+", state->"+player.getState());
                ack.setResult(-1).setResultMsg(ErrorCodeEnum.GAME_50013_1.getCode());
                ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                return;
            }

            if(req.hasBetScore()){
                betScore = req.getBetScore();
            }else{
                //没有指定下注额，那么比牌的下注金额 = “补齐跟注额度”
                betScore = table.getCurrBaseBetScore();
            }

            if(betScore < table.getCurrBaseBetScore()){
                ack.setResult(-2); //比牌下注的积分量小于最低下注额
                logger.error("比牌下注的积分量小于最低下注额");
                ack.setResultMsg(ErrorCodeEnum.GAME_50007_1.getCode());
                ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                return;
            }

            //根据玩法配置信息，判断是否允许“选择指定用户”进行比牌（如果不允许选择用户，那么默认和上家比牌）
            CommonConfigModel commonConfig = table.getCommonConfig();
            if(null == commonConfig){
                throw new Exception("can't found CommonConfig, playType->"+ PlayTypeEnum.classic);
            }
            if(!commonConfig.isChooseSideShowUser()){
                //如果“不允许指定”被比牌玩家，那么服务器端需要判断req中的被比牌用户是否是上家
                PlayerInfo prePlayerInfo = TableUtil.getPreBetPlayer(table,player.getSeatNum());
                if(!targetPlayer.getPlayerId().equals(prePlayerInfo.getPlayerId())){
                    ack.setResult(-3); //不能指定非上家的玩家进行比牌
                    logger.error("不能指定非上家的玩家进行比牌");
                    ack.setResultMsg(ErrorCodeEnum.GAME_50007_2.getCode());
                    ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                    return;
                }
            }

            //比牌的两个玩家中，任何一方都不能是 盲牌
            if(player.getIsBlind() == 1 || targetPlayer.getIsBlind() == 1){
                ack.setResult(-4); //玩家不能是盲牌
                logger.error("玩家不能是盲牌");
                ack.setResultMsg(ErrorCodeEnum.GAME_50007_3.getCode());
                ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
                return;
            }

            table.getOpenCardPlayerIds().clear();
            table.getOpenCardPlayerIds().add(player.getPlayerId());
            table.getOpenCardPlayerIds().add(targetPlayer.getPlayerId());
            //广播事件：通知所有牌桌内玩家，有用户进行比牌操作，玩家进行等待倒计时
            try{
                NoticeBroadcastMessages.applySideShow(table, player, targetPlayer);
            }catch (Exception ex){
                logger.error("SendNotice ERROR：", ex);
            }

            //返回数据
            ack.setUserId(userId);
            ack.setTableId(table.getTableId());
            ack.setGameOrderId(gameOrderId);
            ack.setTargetUserId(targetUserId);
            ack.setBetScore(betScore);
            ack.setCurrPlayScore(player.getPlayScoreStore());
            ack.setResult(1);
            ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));

            //启动倒计时
//            GameLogic.SideShowResultCD(table, player, targetPlayer);
        }catch (Exception ex){
            logger.error("系统异常：userId->"+userId+", gameOrderId->"+gameOrderId+", message->"+ex.getMessage());
            ack.setResult(-1);
            ack.setResultMsg(ErrorCodeEnum.GAME_50002_2.getCode());
            ctx.writeAndFlush(new JoloGame_ApplySideShowAck_50007(ack.build(), header));
        }finally {
            logger.debug("SideShow ACK info: "+ack.toString());
            logger.debug("SideShow ACK bytes length: "+ack.build().toByteArray().length);
            if(null != table){
                logger.debug("All Player info: "+System.getProperty("line.separator") + TableUtil.toStringAllPlayers(table));

                logger.debug("InGame Player info: "+System.getProperty("line.separator") + TableUtil.toStringInGamePlayers(table));
            }
            logger.debug("SideShow over. Table state: "+table.getTableStateEnum());

            long useTimes = System.currentTimeMillis() - time;
            if(useTimes > 10) {
                logger.error("ApplyChooseUser。 耗时->{} 毫秒, reqNum->{}", useTimes, header.reqNum); //TODO:临时增加
            }
        }
    }
}
